package org.hepeng.workx.mybatis.builder.annotation;

import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.builder.annotation.MapperAnnotationBuilder;
import org.apache.ibatis.session.Configuration;
import org.hepeng.workx.extension.DefaultXImpl;
import org.hepeng.workx.util.CompositeObjectProcessor;
import org.hepeng.workx.util.ObjectProcessor;
import org.joor.Reflect;

import java.util.List;

/**
 * @author he peng
 */

@DefaultXImpl
public class ObjectProcessParseMapperAnnotationBuilder extends MapperAnnotationBuilder {

    protected CompositeObjectProcessor objectProcessor = new CompositeObjectProcessor();
    protected boolean isResourceLoaded;

    public ObjectProcessParseMapperAnnotationBuilder(Configuration configuration, Class<?> type ,
                                                     List<ObjectProcessor<MapperAnnotationBuilderParseObjectProcessor.ParseProcessObject, Object>> objectProcessors) {
        super(configuration, type);
        if (CollectionUtils.isNotEmpty(objectProcessors)) {
            objectProcessors.forEach(objProcessor -> this.objectProcessor.addObjectProcessor(objProcessor));
        }
        this.isResourceLoaded = Reflect.on(configuration).call("isResourceLoaded" , type.toString()).get();
    }

    @Override
    public void parse() {
        if (! isResourceLoaded) {
            Reflect thisReflect = Reflect.on(this);
            MapperBuilderAssistant assistant = thisReflect.get("assistant");
            Class<?> type = thisReflect.get("type");
            assistant.setCurrentNamespace(type.getName());
            MapperAnnotationBuilderParseObjectProcessor.ParseProcessObject parseProcessObject =
                    MapperAnnotationBuilderParseObjectProcessor.ParseProcessObject
                    .builder().assistant(assistant)
                    .configuration(thisReflect.get("configuration"))
                    .type(type).build();
            objectProcessor.preProcess(parseProcessObject);
            super.parse();
            objectProcessor.postProcess(parseProcessObject);
        }
    }
}
